import cn.goour.utils.security.impl.MD5Impl
import cn.goour.web.base.tools.MessageManager
import cn.goour.web.base.tools.StringSimilar
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig
import org.slf4j.LoggerFactory
import java.util.*

private var encryptor: StandardPBEStringEncryptor? = null
private val logger = LoggerFactory.getLogger("kotlin.String")

/**
 * 把密文放到配置文件中的时候要注意：
 * ENC(密文)
 */
fun String.encrypt(): String {
    val encryptor = getStandardPBEStringEncryptor()
    val result = encryptor.encrypt(this)
    logger.info("加密 --- 明文：$this,密文：$result")
    return result
}

/**
 * 把密文放到配置文件中的时候要注意：
 * ENC(密文)
 */
fun String.decrypt(): String {
    val encryptor = getStandardPBEStringEncryptor()
    //解密
    val result = encryptor.decrypt(this)
    logger.info("解密 --- 密文：$this,明文：$result")
    return result
}

fun String.decryptNotError(): String {
    val encryptor = getStandardPBEStringEncryptor()
    //解密
    val result = try {
        encryptor.decrypt(this)
    } catch (e: Exception) {
        logger.info("解密出现错误：${e.javaClass.name}")
        ""
    }
    logger.info("解密 --- 密文：$this,明文：$result")
    return result
}

private fun String.getStandardPBEStringEncryptor(): StandardPBEStringEncryptor {
    if (encryptor == null) {
        synchronized(this) {
            if (encryptor == null) {
                //加密工具
                encryptor = StandardPBEStringEncryptor()
                //应用配置
                encryptor!!.setConfig(this.getCryptorConfig())
            }
        }
    }
    return encryptor!!
}

private fun String.getCryptorConfig(): EnvironmentStringPBEConfig {
    //加密配置
    val config = EnvironmentStringPBEConfig()
    config.algorithm = "PBEWithMD5AndDES"
    //自己在用的时候更改此密码
    config.password = "mall"
    return config
}

// 国际化资源获取，简化代码
@Throws(Exception::class)
fun String.keyToI18NValue() = MessageManager.getMsg(this)

fun String.keyToI18NDefault() = this.keyToI18NDefault("")

fun String.keyToI18NDefault(defaultValue: String): String {
    return try {
        this.keyToI18NValue()
    } catch (e: Exception) {
        defaultValue
    }
}

fun String.format(map: Map<String, Any>) = this.format('{', '}', map)

fun String.format(prefix: Char, suffix: Char, map: Map<String, Any>): String {
    var start = -1
    val sb = StringBuffer(this)
    var index: Int = 0
    while (index < sb.length) {
        val c = sb[index]
        if (c == prefix) {
            // 匹配到开始字符
            start = index
        } else if (start > -1 && index > 0 && c == suffix) {
            // 匹配到结束字符
            val myKey = sb.substring(start + 1, index)
            val value = map[myKey]
//            logger.debug("String.format():start = {}, index = $index",start)
            if (value != null) {
                sb.replace(start, index + 1, value.toString())
                index += value.toString().length - (index + 1 - start)
//                logger.debug("String.format():key = $myKey , value = $value")
//                logger.debug("String.format():index = $index, re = $sb")
            }
        }
        index++
    }
    return sb.toString()
}

/**
 * 计算两个字符串的相似度
 */
fun String.getSimilarity(string: String) = StringSimilar.getSimilarity(this, string)
/*
fun main(args: Array<String>) {
    println("houkunlin".encrypt())
    try {
        println("houkunlin".decryptNotError())
        println("".decrypt())
        println("houkunlin".decrypt())
    } catch (e: Exception) {
        e.printStackTrace()
    }
}*/

fun String.MD5(): String {
    return try {
        MD5Impl.getInstance().EncryptionToString(this)
    } catch (e: Exception) {
        UUID.randomUUID().toString()
    }
}